(use-package window-numbering
  :init
  :hook (after-init . window-numbering-mode))

(use-package es-windows
  :ensure t)

(use-package buffer-move
  :ensure t)

(use-package resize-window
  :ensure t
  :init
  (defvar resize-window-dispatch-alist
    '((?n resize-window--enlarge-down " Resize - Expand down" t)
      (?p resize-window--enlarge-up " Resize - Expand up" t)
      (?f resize-window--enlarge-horizontally " Resize - horizontally" t)
      (?b resize-window--shrink-horizontally " Resize - shrink horizontally" t)
      (?r resize-window--reset-windows " Resize - reset window layout" nil)
      (?w resize-window--cycle-window-positive " Resize - cycle window" nil)
      (?W resize-window--cycle-window-negative " Resize - cycle window" nil)
      (?2 split-window-below " Split window horizontally" nil)
      (?3 split-window-right " Slit window vertically" nil)
      (?0 resize-window--delete-window " Delete window" nil)
      (?K resize-window--kill-other-windows " Kill other windows (save state)" nil)
      (?y resize-window--restore-windows " (when state) Restore window configuration" nil)
      (?? resize-window--display-menu " Resize - display menu" nil))
    "List of actions for `resize-window-dispatch-default.
Main data structure of the dispatcher with the form:
\(char function documentation match-capitals\)"))

(use-package winner
  :ensure nil
  :commands (winner-undo winner-redo)
  :hook (after-init . winner-mode)
  :init (setq winner-boring-buffers '("*Completions*"
				      "*Compile-Log*"
				      "*inferior-lisp*"
				      "*Fuzzy Completions*"
				      "*Apropos*"
				      "*Help*"
				      "*cvs*"
				      "*Buffer List*"
				      "*Ibuffer*"
				      "*esh command on file*")))

(use-package popper
  :defines popper-echo-dispatch-actions
  :commands popper-group-by-directory
  :bind (:map popper-mode-map
	      ("s-`" . popper-toggle-latest)
	      ("s-o"   . popper-cycle)
	      ("M-`" . popper-toggle-type))
  :hook (emacs-startup . popper-mode)
  :init
  (setq popper-reference-buffers
	'("\\*Messages\\*"
	  "Output\\*$" "\\*Pp Eval Output\\*$"
	  "\\*Compile-Log\\*"
	  "\\*Completions\\*"
	  "\\*Warnings\\*"
	  "\\*Flymake diagnostics.*\\*"
	  "\\*Async Shell Command\\*"
	  "\\*Apropos\\*"
	  "\\*Backtrace\\*"
	  "\\*prodigy\\*"
	  "\\*Calendar\\*"
	  "\\*Embark Actions\\*"
	  "\\*Finder\\*"
	  "\\*Kill Ring\\*"
	  "\\*Embark Export:.*\\*"
	  "\\*Edit Annotation.*\\*"
	  "\\*Flutter\\*"
	  bookmark-bmenu-mode
	  lsp-bridge-ref-mode
	  comint-mode
	  compilation-mode
	  help-mode helpful-mode
	  tabulated-list-mode
	  Buffer-menu-mode
	  occur-mode
	  gnus-article-mode devdocs-mode
	  grep-mode occur-mode rg-mode deadgrep-mode ag-mode pt-mode
	  ivy-occur-mode ivy-occur-grep-mode
	  process-menu-mode list-environment-mode cargo-process-mode
	  youdao-dictionary-mode osx-dictionary-mode fanyi-mode

	  "^\\*eshell.*\\*.*$" eshell-mode
	  "^\\*shell.*\\*.*$"  shell-mode
	  "^\\*terminal.*\\*.*$" term-mode
	  "^\\*vterm.*\\*.*$"  vterm-mode

	  "\\*DAP Templates\\*$" dap-server-log-mode
	  "\\*ELP Profiling Restuls\\*" profiler-report-mode
	  "\\*Flycheck errors\\*$" " \\*Flycheck checker\\*$"
	  "\\*Paradox Report\\*$" "\\*package update results\\*$" "\\*Package-Lint\\*$"
	  "\\*[Wo]*Man.*\\*$"
	  "\\*ert\\*$" overseer-buffer-mode
	  "\\*gud-debug\\*$"
	  "\\*lsp-help\\*$" "\\*lsp session\\*$"
	  "\\*quickrun\\*$"
	  "\\*tldr\\*$"
	  "\\*vc-.*\\*$"
	  "\\*eldoc\\*"
	  "^\\*elfeed-entry\\*$"
	  "^\\*macro expansion\\**"

	  "\\*Agenda Commands\\*" "\\*Org Select\\*" "\\*Capture\\*" "^CAPTURE-.*\\.org*"
	  "\\*Gofmt Errors\\*$" "\\*Go Test\\*$" godoc-mode
	  "\\*docker-containers\\*" "\\*docker-images\\*" "\\*docker-networks\\*" "\\*docker-volumes\\*"
	  "\\*prolog\\*" inferior-python-mode inf-ruby-mode swift-repl-mode
	  "\\*rustfmt\\*$"
	  ;; rustic-compilation-mode rustic-cargo-clippy-mode
	  ;; rustic-cargo-outdated-mode rustic-cargo-test-moed
	  ))

  (when (display-grayscale-p)
    (setq popper-mode-line
	  '(:eval
	    (concat
	     (propertize " " 'face 'mode-line-emphasis)
	     (all-the-icons-octicon "pin" :height 0.9 :v-adjust 0.0 :face 'mode-line-emphasis)
	     (propertize " " 'face 'mode-line-emphasis)))))

  (setq popper-echo-dispatch-actions t)
  (setq popper-group-function nil)
  :config
  (popper-echo-mode 1)

  (with-no-warnings
    (defun my-popper-fit-window-height (win)
      "Determine the height of popup window WIN by fitting it to the buffer's content."
      (fit-window-to-buffer
       win
       (floor (frame-height) 3)
       (floor (frame-height) 3)))
    (setq popper-window-height #'my-popper-fit-window-height)

    (defun popper-close-window-hack (&rest _)
      "Close popper window via `C-g'."
      ;; `C-g' can deactivate region
      (when (and (called-interactively-p 'interactive)
		 (not (region-active-p))
		 popper-open-popup-alist)
	(let ((window (caar popper-open-popup-alist)))
	  (when (window-live-p window)
	    (delete-window window)))))
    (advice-add #'keyboard-quit :before #'popper-close-window-hack)))

(use-package tab-bar
  :ensure nil
  :init
  (tab-bar-mode t)
  (setq tab-bar-new-tab-choice "*scratch*") ;; buffer to show in new tabs
  (setq tab-bar-close-button-show nil)      ;; hide tab close / X button
  (setq tab-bar-show 1)                     ;; hide bar if <= 1 tabs open
  (setq tab-bar-format '(tab-bar-format-tabs tab-bar-separator))


  (defvar ct/circle-numbers-alist
    '((0 . "⓪")
      (1 . "①")
      (2 . "②")
      (3 . "③")
      (4 . "④")
      (5 . "⑤")
      (6 . "⑥")
      (7 . "⑦")
      (8 . "⑧")
      (9 . "⑨"))
    "Alist of integers to strings of circled unicode numbers.")

  (defun ct/tab-bar-tab-name-format-default (tab i)
    (let ((current-p (eq (car tab) 'current-tab))
	  (tab-num (if (and tab-bar-tab-hints (< i 10))
		       (alist-get i ct/circle-numbers-alist) "")))
      (propertize
       (concat tab-num
	       " "
	       (alist-get 'name tab)
	       (or (and tab-bar-close-button-show
			(not (eq tab-bar-close-button-show
				 (if current-p 'non-selected 'selected)))
			tab-bar-close-button)
		   "")
	       " ")
       'face (funcall tab-bar-tab-face-function tab))))
  (setq tab-bar-tab-name-format-function #'ct/tab-bar-tab-name-format-default)
  (setq tab-bar-tab-hints t))

(use-package tabspaces
  ;; use this next line only if you also use straight, otherwise ignore it.
  :hook (after-init . tabspaces-mode) ;; use this only if you want the minor-mode loaded at startup.
  :commands (tabspaces-switch-or-create-workspace
	     tabspaces-open-or-create-project-and-workspace)
  :custom
  (tabspaces-use-filtered-buffers-as-default t)
  (tabspaces-default-tab "Default")
  (tabspaces-remove-to-default t)
  (tabspaces-include-buffers '("*scratch*"))
  ;; maybe slow
  ;; (tabspaces-session t)
  ;; (tabspaces-session-auto-restore t)
  :config
  ;; Filter Buffers for Consult-Buffer

  (with-eval-after-load 'consult
    ;; hide full buffer list (still available with "b" prefix)
    (consult-customize consult--source-buffer :hidden nil :default nil)
    ;; set consult-workspace buffer list
    (defvar consult--source-workspace
      (list :name "Workspace Buffers"
	    :narrow ?w
	    :history 'buffer-name-history
	    :category 'buffer
	    :state #'consult--buffer-state
	    :default t
	    :items (lambda () (consult--buffer-query
			       :predicate #'tabspaces--local-buffer-p
			       :sort 'visibility
			       :as #'buffer-name)))

      "Set workspace buffer list for consult-buffer.")
    (add-to-list 'consult-buffer-sources 'consult--source-workspace)))

  (custom-set-faces
   '(tab-bar ((t (:inherit mode-line))))
   '(tab-bar-tab ((t (:inherit mode-line :foreground "#999944"))))
   '(tab-bar-tab-inactive ((t (:inherit mode-line-inactive :foreground "white")))))
(provide 'init-window)
